package com.niit.onlinemusicserver.algorithm;


import com.niit.onlinemusicserver.model.domain.Collect;
import com.niit.onlinemusicserver.model.domain.DownloadRecord;
import com.niit.onlinemusicserver.model.domain.PayItem;
import com.niit.onlinemusicserver.model.domain.PlayRecord;
import com.niit.onlinemusicserver.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class RecommendTask {

    @Autowired
    private ConsumerService consumerService;
    @Autowired
    private SongService songService;
    @Autowired
    private PlayRecordService playRecordService;
    @Autowired
    private DownLoadRecordService downLoadRecordService;
    @Autowired
    private CollectService collectionService;
    @Autowired
    private RecommendService recommendService;

    @Autowired
    private PayService payService;

    /**
     * KNN k值
     * 目前系统用户很少
     */
    public static final int K = 10;

    /**
     * 基于最近邻用户的协同过滤给用户推荐歌曲的数量 n值
     * 歌曲很少
     */
    public static final int N = 15;
    /**
     * @Description: 推荐歌曲方法
     * 使用 Cron 表达式配置每 30s 执行一次该方法
     **/
    @Scheduled(cron = "*/30 * * * * ?")
    public void recommend(){
        /** Step1:准备偏好数据 */
        //用户-歌曲 推荐列表
        Map<Integer, Integer[]> user2songRecMatrix = new HashMap<Integer, Integer[]>();
        //获取用户
        List<Integer> userIdList = consumerService.getAllUserIds();
        //获取歌曲
        List<Integer> songIdList = songService.getAllSongIds();
        //获取用户的播放记录
        List<PlayRecord> playList = playRecordService.getAllRecords();
        //获取用户的下载记录
        List<DownloadRecord> downloadList = downLoadRecordService.getAllRecords();
        //获取用户的收藏记录
        List<Collect> collectionList = collectionService.getAllRecords();

        //获取用户购买记录
        List<PayItem> payItemList = payService.getAllPayItemList();

        //Step2 用户-歌曲 “评分”矩阵
        Map<Integer, float[]> user2songRatingMatrix = DataTranslate.getFrequencyMatrix(userIdList, songIdList,
                downloadList, playList, collectionList,payItemList);

        /** Step3:计算用户相似性，获取用户的 K 个近邻用户 */
        Map<Integer, Integer[]> userKNNMatrix = UserKNN.getKNN(userIdList, user2songRatingMatrix, K);
        /** Step4：生成推荐数据：基于用户相似性的协同过滤 */
        user2songRecMatrix = CollaborativeFiltering.userKNNBasedCF(userIdList, userKNNMatrix,
                user2songRatingMatrix, songIdList, N);
        //将打印语句替换为调用更新推荐数据的 Service 方法：
        recommendService.updatePersonalRecInfo(user2songRecMatrix);
    }
}